<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>数据拷贝</title>
</head>
<body>
  <script>
    /*
      数据类型：基本类型 ， 引用类型
      基本类型：String, Number, Boolean, undefind, null
      引用类型： Object

      1、基本类型数据拷贝，直接赋值就行
      2、引用类型拷贝，直接赋值，只是将对象在内存中的地址赋值过去
    */

    /***********************************************************************************************************************/


      //直接赋值
      var arr1 = [1,2,3,4,5];
      var arr11 = arr1;
      arr1[0] = '直接赋值'
      console.log(arr1, arr11); //arr1改变，arr11也会跟着改变

    // 数组的拷贝
    
    //用扩展运算符，浅拷贝
    var arr2 = [1,2,['ni','hao'],4,5];
    var arr22 = [...arr2];
    arr2[0] = '扩展运算符';
    arr2[2][0] = '你'
    console.log(arr2, arr22); //arr2改变，不会影响arr22；但是改变第二层，就会受影响了

    //用concat(),浅拷贝  concat()本来是用来连接2个数组的，当concat中没有参数时，就是用来拷贝数组的  
    var arr3 = [1,2,['ni','hao'],4,5];
    var arr33 = arr3.concat();
    arr3[0] = 'concat';
    arr3[2][0] = '你'
    console.log(arr3, arr33); //arr3改变，不会影响arr33

    //用for循环

    //ps: 数组中出现的这几种方法都是浅拷贝，如何实现深拷贝？



  /***********************************************************************************************************************/

  // 对象的拷贝
  
  // *******浅拷贝, 改变不了第一层，可以改变第二层********
  // 1、for in
  var book1 = {
        name:"妙味修炼之道",
        picture:{
            small:'../这是小的',
            middle:'../这是中等的',
            large:'../这是大的',
        }
      }
        
  var obj1 = {}
  for(var v in book1){
    obj1[v] = book1[v]
  }
  
  book1.name = 'for in';
  book1.picture.small = 'big';
  console.log(obj1,book1);  //book1中的small改变了，obj1也改变了


  //2、assign
  // Object.assign (target,...sources)	 target:目标对象 ...sources：原对象 目标对象，一般为{}，这样就不会有对象被改变

  var book2 = {
    name:"妙味修炼之道",
    picture:{
      small:'../这是小的',
      middle:'../这是中等的',
      large:'../这是大的',
    }
  }
  var obj2 = Object.assign({}, book2)
  book2.name = 'assign';
  book2.picture.small = 'big';
  console.log(obj2,book2);  //book2中的small改变了，obj2也改变了

  
  // *******深拷贝********

  // 1、JSON

  var book3 = {
    name:"妙味修炼之道",
    picture:{
      small:'../这是小的',
      middle:'../这是中等的',
      large:'../这是大的',
    }
  }

  var obj3 = JSON.parse(JSON.stringify(book3));
  book3.name = 'JSON';
  book3.picture.small = 'big';
  console.log(obj3,book3);  //book3改变，obj3不受影响

  /*
    原理：JSON.stringify()将对象转成了字符串，字符串是基本类型，基本类型存储时会重新开辟内存。此时再转成对象，则完成了深拷贝
    ps: 但是这种方法，也有缺陷，因为JSON 转数据是有要求的，无法转换function, undefined。当obj中有function时，是无法拷贝的
  */

  // 2、若是想拷贝function呢？用递归，见006递归拷贝

            
            



  </script>
</body>
</html>